<template>
  <div class="swiper-container" ref="swiperContainer">
    <div class="swiper-wrapper">
      <div class="swiper-slide" v-for="(item, index) in data" :key="item.id">
        <div class="swiper-slide__media">
          <img
            v-if="item.type === 'Image'"
            class="swiper-slide__media-img"
            :src="item.imgSrc"
            :alt="item.alt"
          />
          <div class="video-player" v-else-if="item.type === 'Video'">
            <video
              :ref="(el) => setVideoRef(el, index)"
              playsinline
              :poster="item.imgSrc"
              @ended="onVideoEnded"
            >
              <source :src="item.videoSrc" type="video/mp4" />
            </video>
          </div>
        </div>

        <a :href="item.link" target="_blank" class="swiper-slide__link"></a>
        <div class="swiper-slide__body">
          <div class="swiper-slide__body__title text-center">{{ item.title }}</div>
          <template v-if="item.type === 'Video'">
            <button type="button" class="swiper-slide__body__play" v-if="!isPlaying" @click.stop="playVideo"></button>
            <button type="button" class="swiper-slide__body__link" @click.stop="handlePlayAll">观看完整视频</button>
          </template>
        </div>
      </div>
    </div>

    <!-- 分页器 -->
    <div class="swiper-pagination"></div>

    <!-- 导航按钮 -->
    <div class="swiper-button-next"></div>
    <div class="swiper-button-prev"></div>
  </div>

  <a-modal v-model:visible="showVideo" :footer="false" width="1200px" @cancel="handleCancel">
    <template #title>
      观看完整视频
    </template>
    <div class="video-box">
      <video
        ref="videoElement"
        controls
      >
        <source :src="videoSrc" type="video/mp4" />
      </video>
    </div>
  </a-modal>
</template>

<script lang="ts" setup>
import { ref, onMounted, onUnmounted, nextTick, watch } from 'vue'

interface SwiperItem {
  id: string | number
  type: 'Image' | 'Video'
  imgSrc: string
  alt?: string
  videoSrc?: string
  link?: string
  title?: string
  isExternal: boolean
}

const props = defineProps<{
  data: SwiperItem[],
  imageInterval?: number,
  videoAutoNext?: boolean
}>()

// 响应式变量
const swiperContainer = ref<HTMLElement>()
let swiperInstance: any = null
let currentSlideIndex = 0

// 图片自动切换定时器
let imageTimer: ReturnType<typeof setTimeout> | null = null

// 动态导入 Swiper
let Swiper: any = null
let Navigation: any = null
let Pagination: any = null
let Autoplay: any = null

// 初始化 Swiper
const initSwiper = async () => {
  try {
    // 动态导入 Swiper 模块
    const swiperModule = await import('swiper' as any)
    const { Navigation: NavigationModule, Pagination: PaginationModule, Autoplay: AutoplayModule } = await import('swiper/modules' as any)

    Swiper = swiperModule.Swiper
    Navigation = NavigationModule
    Pagination = PaginationModule
    Autoplay = AutoplayModule
    if (swiperContainer.value) {
      swiperInstance = new Swiper(swiperContainer.value, {
        modules: [Navigation, Pagination, Autoplay],
        autoHeight: false, // 禁用自适应高度，使用固定高度
        speed: 1000,
        effect: 'fade',
        fadeEffect: {
          crossFade: true
        },
        navigation: {
          nextEl: '.swiper-button-next',
          prevEl: '.swiper-button-prev',
        },
        pagination: {
          el: '.swiper-pagination',
          clickable: true,
        },
        on: {
          slideChange: (swiper: any) => {
            currentSlideIndex = swiper.activeIndex
            handleSlideChange(currentSlideIndex)
          },
          // 用户交互时重置定时器
          touchStart: () => {
            clearImageTimer()
          },
          touchEnd: () => {
            // 延迟一点时间再启动定时器，避免立即触发
            setTimeout(() => {
              const currentItem = props.data[currentIndex.value]
              if (currentItem && currentItem.type === 'Image') {
                startImageTimer()
              }
            }, 100)
          }
        }
      })
    }
  } catch (error) {
    console.error('❌ Swiper组件: 初始化失败:', error)
  }
}

const currentIndex = ref<number>(0)

// 清除图片定时器
const clearImageTimer = () => {
  if (imageTimer) {
    clearTimeout(imageTimer)
    imageTimer = null
  }
}

// 启动图片自动切换定时器
const startImageTimer = () => {
  clearImageTimer()
  const currentItem = props.data[currentIndex.value]

  // 只有当前是图片类型时才启动定时器
  if (currentItem && currentItem.type === 'Image') {
    const interval = props.imageInterval || 5000 // 默认5秒
    imageTimer = setTimeout(() => {
      if (swiperInstance) {
        swiperInstance.slideNext()
      }
    }, interval)
  }
}

// 处理幻灯片切换
const handleSlideChange = (index: number) => {
  // 清除之前的定时器
  clearImageTimer()
  pauseVideo()
  currentIndex.value = index

  const currentItem = props.data[currentIndex.value]
  if (currentItem.type === 'Video') {
    playVideo()
  } else if (currentItem.type === 'Image') {
    // 启动图片自动切换定时器
    startImageTimer()
  }
}

// 视频播放完成
const onVideoEnded = () => {
  isPlaying.value = false

  // 如果启用了视频自动切换下一项
  if (props.videoAutoNext !== false && swiperInstance) { // 默认为true，除非明确设置为false
    setTimeout(() => {
      swiperInstance.slideNext()
    }, 200) // 延迟200ms后切换，给用户一点反应时间
  }
}

// 保存所有 video 元素的 ref
const videoElements = ref<HTMLVideoElement[]>([])
// 设置 ref 到数组中
import type { ComponentPublicInstance } from 'vue'

const setVideoRef = (el: Element | ComponentPublicInstance | null, index: number) => {
  // If el is a Vue component instance, get its $el property
  const element = (el && '$el' in el) ? (el as ComponentPublicInstance).$el : el
  if (element instanceof HTMLVideoElement) {
    videoElements.value[index] = element
  }
}

const isPlaying = ref<boolean>(false)
// 播放视频
const playVideo = () => {
  if (videoElements.value[currentIndex.value]) {
    videoElements.value[currentIndex.value].play()
    isPlaying.value = true
    // 播放视频时清除图片定时器
    clearImageTimer()
  }
}

// 暂停视频
const pauseVideo = () => {
  if (videoElements.value[currentIndex.value]) {
    videoElements.value[currentIndex.value].pause()
    isPlaying.value = false
  }
}

const showVideo = ref<boolean>(false)
const videoElement = ref<HTMLVideoElement>()
const videoSrc = ref<string>()
const handlePlayAll = () => {
  pauseVideo()
  videoSrc.value = props.data[currentIndex.value].videoSrc
  nextTick(() => {
    showVideo.value = true
    videoElement.value?.play()
  })
}

const handleCancel = () => {
  videoElement.value?.pause()
  showVideo.value = false
}

// 生命周期
onMounted(async () => {
  await initSwiper()
  handleSlideChange(0)
})

onUnmounted(() => {
  // 清理定时器
  clearImageTimer()

  // 销毁 Swiper 实例
  if (swiperInstance) {
    swiperInstance.destroy(true, true)
  }
})

defineExpose({
  initSwiper
})
</script>

<style lang="scss" scoped> 
// Swiper 容器样式
.swiper-container {
  position: relative;
  width: 100%;
  height: auto;
}

.swiper-slide {
  position: relative;
  width: 100%;
  aspect-ratio: 1 / 0.455; /* 宽高比为 1 : 0.455，即 height = width * 45.5% */
  overflow: hidden; // 隐藏超出部分
}

@media (min-width: 768px) {
  .swiper-slide {
    min-height:400px; // 移动端固定高度
  }
}

.swiper-slide__link {
  position: absolute;
  width: 100%;
  height: 100%;
  left: 0;
  top: 0;
  z-index: 2;
}

.swiper-slide__media {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 1;
}

.swiper-slide__media img {
  width: 100%;
  height: 100%;
  object-fit: cover; // 裁剪多余部分，保持宽高比
  display: block;
}

.swiper-slide__media .video-player {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

.swiper-slide__media .video-player video {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: cover; // 裁剪多余部分，保持宽高比
}

.swiper-slide__body {
  position: absolute;
  top: 0;
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  z-index: 2;
  pointer-events: none;
  padding: 20px;
  box-sizing: border-box;
}

.swiper-slide__body__title {
  color: #fff;
  margin-bottom: 8px;
  font-size: 40px;
  font-weight: 500;
  line-height: 1.2;
  letter-spacing: .02em;
  text-shadow: 0 2px 4px rgba(0, 0, 0, 0.5);
}

@media (max-width: 1023.98px) {
  .swiper-slide__body__title {
    font-size: 32px;
    font-weight: 500;
    line-height: 1.2;
    letter-spacing: .02em;
  }
}

@media (max-width: 767.98px) {
  .swiper-slide__body__title {
    font-size: 24px;
    line-height: 1.09;
  }
}

.swiper-slide__body__link {
  background: none;
  border: none;
  font-size: 16px;
  font-weight: 500;
  line-height: 1.5;
  letter-spacing: .01em;
  color: #fff;
  text-decoration: none;
  margin-bottom: 40px;
  padding: 0 0 1px;
  position: relative;
  pointer-events: visible;
  cursor: pointer;
}

@media (max-width: 1023.98px) {
  .swiper-slide__body__link {
    line-height: 1.25;
    letter-spacing: .04em;
  }
}

@media (max-width: 767.98px) {
  .swiper-slide__body__link {
    font-size: 14px;
    line-height: 1.285;
    letter-spacing: .02em;
    margin-bottom: 30px;
  }
}

.swiper-slide__body__link:after {
  content: "";
  width: 100%;
  height: 1px;
  background-color: #fff;
  right: 0;
  bottom: 0;
  position: absolute;
}

.swiper-slide__body__link--hide {
  opacity: 0;
  pointer-events: none;
}

.swiper-slide__body__link:hover:after {
  animation: link-animation .6s;
  animation-fill-mode: both;
}

@keyframes link-animation {
  0% {
    width: 100%;
    right: 0;
    left: auto;
  }
  50% {
    width: 0;
    right: 0;
    left: auto;
  }
  50.1% {
    left: 0;
    right: auto;
  }
  to {
    width: 100%;
    left: 0;
    right: auto;
  }
}

.swiper-slide__body__play {
  position: absolute;
  border: none;
  left: 50%;
  top: 40%;
  width: 52.5px;
  height: 52.5px;
  transform: translate(-50%, -50%);
  background-image: url();
  background-position: 50%;
  background-size: cover;
  background-repeat: no-repeat;
  background-color: transparent;
  z-index: 3;
  transition: opacity .3s ease-in-out;
  pointer-events: visible;
  cursor: pointer;
}

.swiper-slide__body__play--hide {
  pointer-events: none;
  opacity: 0;
}

// Swiper 导航按钮样式
.swiper-button-next,
.swiper-button-prev {
  color: #fff;
  background: rgba(0, 0, 0, 0.3);
  border-radius: 50%;
  width: 44px;
  height: 44px;
  margin-top: -22px;

  &:after {
    font-size: 18px;
  }

  &:hover {
    background: rgba(0, 0, 0, 0.5);
  }
}

// Swiper 分页器样式
.swiper-pagination {
  bottom: 20px;

  :deep(.swiper-pagination-bullet) {
    background: rgba(255, 255, 255, 0.5);
    opacity: 1;

    &.swiper-pagination-bullet-active {
      background: #fff;
    }
  }
}

// 响应式调整
@media (max-width: 767.98px) {
  .swiper-button-next,
  .swiper-button-prev {
    width: 36px;
    height: 36px;
    margin-top: -18px;

    &:after {
      font-size: 14px;
    }
  }

  .swiper-pagination {
    bottom: 15px;
  }
}

.video-box {
  width: 1200px;
  height: auto;

  video {
    width: 100%;
    height: 100%;
  }
}
</style>